package com.emip.job;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.emip.bean.AlarmLogBean;
import com.emip.bean.AlterLogBean;
import com.emip.bean.HourStoreBean;
import com.emip.bean.SiteBean;
import com.emip.bean.SiteItemBean;
import com.emip.bean.Store;
import com.emip.job.method.DayMethod;
import com.emip.job.method.HourMethod;
import com.emip.job.method.MonthMethod;
import com.emip.job.method.QuarterMethod;
import com.emip.job.method.WeekMethod;
import com.emip.job.method.YearMethod;
import com.emip.service.AlarmLogService;
import com.emip.service.AlterLogService;
import com.emip.service.ExpFlagService;
import com.emip.service.HourStoreService;
import com.emip.service.SiteItemService;
import com.emip.service.SiteService;
import com.emip.util.ReportFormat;
import com.emip.util.Util;
import com.emip.util.report.Statistics;


@Component
public class ReportJob {

	static Logger logger = Logger.getLogger(ReportJob.class);
	SimpleDateFormat dateFormat;
	
	@Autowired
	SiteItemService siteItemService;
	
	@Autowired
	ExpFlagService expFlagService;
	
	@Autowired
	HourMethod hourMethod;
	
	@Autowired
	DayMethod dayMethod;
	
	@Autowired
	WeekMethod weekMethod;
	
	@Autowired
	MonthMethod monthMethod;
	
	@Autowired
	QuarterMethod quarterMethod;
	
	@Autowired
	YearMethod yearMethod;
	
	@Autowired
	AlterLogService alterLogService;
	
	@Autowired
	HourStoreService hourStoreService;
	
	@Autowired
	SiteService siteService;
	
	@Autowired
	AlarmLogService alarmLogService;
	
	public void work() {
		Calendar cal = Calendar.getInstance();
		statistic(cal);
	}
	
	public void work (Calendar cal) {
		statistic(cal);
	}
	
	//
	private void statistic(Calendar cal) {
		Statistics statistic = new Statistics(null, siteItemService.getAll(), expFlagService.getAll());
		
		hourMethod.doWork((Calendar) cal.clone(), statistic);
		//计算天
		if (cal.get(Calendar.HOUR_OF_DAY) == 0) {
			dayMethod.doWork((Calendar) cal.clone(), statistic);
		}
		//周
		if (cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
			weekMethod.doWork((Calendar) cal.clone(), statistic);
		}
		//月
		if (cal.get(Calendar.DAY_OF_MONTH) == 1) {
			monthMethod.doWork((Calendar) cal.clone(), statistic);
			//季
			quarterMethod.doWork((Calendar) cal.clone(), statistic);
			//年
			yearMethod.doWork((Calendar) cal.clone(), statistic);
		}
		
		//每天计算更新
		if (cal.get(Calendar.HOUR_OF_DAY) == 0) {
			reStatistic(statistic);
			logAlarm((Calendar) cal.clone());
		}
	}
	
	public void logAlarm(Calendar cal) {
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-mm-dd");
		cal.set(Calendar.DATE, cal.get(Calendar.DATE) - 1);
		String date = sf.format(cal.getTime());
		String startDate = date + " 0";
		String endDate = date + " 24";
		List<HourStoreBean> hours = 
				hourStoreService.getByTimespan(startDate, endDate, null, null);
		for (int i = 0; i < hours.size(); i++) {
			HourStoreBean store = hours.get(i);
			SiteItemBean siteItem = 
					siteItemService.findSiteItem(store.getSiteID(), store.getItemID());
			Double value = Double.parseDouble(store.getValue());
			if (value.compareTo(siteItem.geteMinValue()) < 0  || 
					value.compareTo(siteItem.geteMaxValue()) > 0) {
				store.setFlag(Statistics.EXCEED_FLAG);
			}
			if (Util.trim(store.getFlag()) != "") {
				AlarmLogBean alarmLog = new AlarmLogBean();
				alarmLog.setItem(store.getItem());
				alarmLog.setSite(store.getSite());
				alarmLog.setValue(store.getValue());
				alarmLog.setFlag(store.getFlag());
				
				SiteBean site = siteService.getSiteByID(store.getSiteID());
				alarmLog.setContact(site.getContact());
				alarmLog.setMobile(site.getMobile());
				alarmLog.setType("HOUR");
				alarmLog.setLogType("ALARM");
				alarmLogService.merge(alarmLog);
			}
			
			
		}
	}
	
	public void reStatistic(Statistics statistic) {
		String[] types = new String[]{"Second", "Hour", "Day", "Week", "Month", "Quarter", "Year"};
		for (String type : types) {
			List<AlterLogBean> logs = alterLogService.getAll(type, "F");
			String currentDate = null;
			String currentSite = null;
			String currentItem = null;
			Iterator<AlterLogBean> iterator = logs.iterator();
			while (iterator.hasNext()) {
				AlterLogBean log = iterator.next();
				log.setFlag("T");//将其置为已被影响
				alterLogService.merge(log);
				if (!"T".equalsIgnoreCase(log.getIsTemp())) {
					changeValue(log);//覆盖统计
				}
				
				String upperDate = getUpperDate(log);
				
				if (log.getSite().getId() != currentSite 
						|| log.getItem().getId() != currentItem
						|| upperDate != currentDate) {
					try {
						statistic(log, statistic);
					} catch (ParseException e) {
						e.printStackTrace();
					}
					currentDate = log.getDate();
					currentSite = log.getSite().getId();
					currentItem = log.getItem().getId();
				}
				
//				if (currentDate == null || currentDate == "") {
//					currentDate = Util.trim(log.getDate());
//					continue;
//				}
//				if (currentDate != log.getDate()) {
//					try {
//						statistic(log, statistic);
//					} catch (ParseException e) {
//						e.printStackTrace();
//					}
//					currentDate = log.getDate();
//				}
			}
			
		}
		
	}
	
	public String getUpperDate(AlterLogBean log) {
		Calendar cal = Calendar.getInstance();
		String date = log.getDate();
		String type = log.getType();
		
		try {
			if (type == "Second") {
				SimpleDateFormat sf = new SimpleDateFormat(ReportFormat.SECONDFORMAT);
				cal.setTime(sf.parse(date));
				cal.set(Calendar.HOUR, cal.get(Calendar.HOUR) + 1);
				sf = new SimpleDateFormat(ReportFormat.HOURFORMAT);
				return sf.format(cal.getTime());
			} else if (type == "Hour") {
				SimpleDateFormat sf = new SimpleDateFormat(ReportFormat.HOURFORMAT);
				cal.setTime(sf.parse(date));
				cal.set(Calendar.DAY_OF_MONTH, cal.get(Calendar.DAY_OF_MONTH) + 1);
				sf = new SimpleDateFormat(ReportFormat.DAYFORMAT);
				return sf.format(cal.getTime());
			} else if (type == "Day") {
				SimpleDateFormat sf = new SimpleDateFormat(ReportFormat.DAYFORMAT);
				cal.setTime(sf.parse(date));
				cal.set(Calendar.WEEK_OF_YEAR, cal.get(Calendar.WEEK_OF_YEAR) + 1);
				sf = new SimpleDateFormat(ReportFormat.WEEKFORMAT);
				return sf.format(cal.getTime());
			} else if (type == "Month") {
				String[] dates = date.split("年|月");
				cal.set(Calendar.YEAR, Integer.parseInt(dates[0]));
				cal.set(Calendar.DAY_OF_MONTH, 1);
				cal.set(Calendar.MONTH, Integer.parseInt(dates[1]) + 3);
				SimpleDateFormat sf = new SimpleDateFormat(ReportFormat.MONTHFORMAT);
				return sf.format(cal.getTime());
			} else {
				return log.getDate();
			}
		} catch (Exception e) {
			
		}
		return log.getDate();
	}
	
	private void changeValue(AlterLogBean log) {
		String type = log.getType();
		if (type == "Second") {
			//second的值不会被统计所覆盖，因此不需要再次覆盖
		} else if (type == "Hour") {
			hourMethod.merge(log);
		} else if (type == "Day") {
			dayMethod.merge(log);
		} else if (type == "Week") {
			weekMethod.merge(log);
		} else if (type == "Month") {
			monthMethod.merge(log);
		} else if (type == "Quarter") {
			quarterMethod.merge(log);
		} else if (type == "Year") {
			yearMethod.merge(log);
		}
	}

	public void statistic(AlterLogBean log, Statistics statistic) throws ParseException {
		Calendar cal = Calendar.getInstance();
		String type = log.getType();
		String date = log.getDate();
		String itemId = log.getItem().getId();
		String siteId = log.getSite().getId();
		
		if (type == "Second") {
			SimpleDateFormat sf = new SimpleDateFormat(ReportFormat.SECONDFORMAT);
			cal.setTime(sf.parse(date));
			cal.set(Calendar.HOUR, cal.get(Calendar.HOUR) + 1);
			Store store = 
					hourMethod.comput(cal, statistic, new String[]{itemId}, siteId);
			if (store == null) return;
			log.setDate(store.getTimeLabel());
			log.setFlag("F");
			log.setId(0);
			log.setType("Hour");
			log.setIsTemp("T");
			log.setNewvalue(store.getValue());
			alterLogService.merge(log);
		} else if (type == "Hour") {
			SimpleDateFormat sf = new SimpleDateFormat(ReportFormat.HOURFORMAT);
			cal.setTime(sf.parse(date));
			cal.set(Calendar.DAY_OF_MONTH, cal.get(Calendar.DAY_OF_MONTH) + 1);
			Store store = 
					dayMethod.comput(cal, statistic, new String[]{itemId}, siteId);
			if (store == null) return;
			log.setDate(store.getTimeLabel());
			log.setFlag("F");
			log.setId(0);
			log.setType("Day");
			log.setIsTemp("T");
			log.setNewvalue(store.getValue());
		} else if (type == "Day") {
			SimpleDateFormat sf = new SimpleDateFormat(ReportFormat.DAYFORMAT);
			//Week
			cal.setTime(sf.parse(date));
			cal.set(Calendar.WEEK_OF_YEAR, cal.get(Calendar.WEEK_OF_YEAR) + 1);
			weekMethod.comput(cal, statistic, new String[]{itemId}, siteId);
			
			//Month
			cal.setTime(sf.parse(date));
			cal.set(Calendar.MONTH, cal.get(Calendar.MONTH) + 1);
			Store store = 
					monthMethod.comput(cal, statistic, new String[]{itemId}, siteId);
			if (store == null) return;
			log.setDate(store.getTimeLabel());
			log.setFlag("F");
			log.setId(0);
			log.setType("Month");
			log.setIsTemp("T");
			log.setNewvalue(store.getValue());
		} else if (type == "Month") {
			//Quarter
			String[] dates = date.split("年|月");
			cal.set(Calendar.YEAR, Integer.parseInt(dates[0]));
			cal.set(Calendar.DAY_OF_MONTH, 1);
			cal.set(Calendar.MONTH, Integer.parseInt(dates[1]) + 3);
			quarterMethod.comput(cal, statistic, new String[]{itemId}, siteId);
			
			//Year
			cal.set(Calendar.YEAR, Integer.parseInt(dates[0]) + 1);
			yearMethod.comput(cal, statistic, new String[]{itemId}, siteId);
		}
	}
	
}
